package com.apache.client.common;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXB;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 用于生成和转换对象为xml格式字符串的工具类
 * @author xhe
 */
public class XmlStrUtil {

	//获取xml格式头标题；如：&lt;?xml version='1.0' encoding='gb2312'?&gt;

	public static String getXmlHeadGB2312() {
		return "<?xml version=\"1.0\" encoding=\"gb2312\"?>";
	}
	public static String getXmlHeadUTF8() {
		return "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
	}
	public static String getXmlHeadGBK() {
		return "<?xml version=\"1.0\" encoding=\"gbk\"?>";
	}

	/**
	 */
	public static String getValue(String XML, String nodeName) throws SAXException, IOException {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		;
		org.w3c.dom.Document doc = null;
		try {
			db = dbf.newDocumentBuilder();
			doc = db.parse(new ByteArrayInputStream(XML.getBytes()));
		} catch (ParserConfigurationException e1) {
			e1.printStackTrace();
		}

		//得到根节点
		org.w3c.dom.Element root = doc.getDocumentElement();
		NodeList nl = root.getElementsByTagName(nodeName);
		org.w3c.dom.Element e = (org.w3c.dom.Element) nl.item(0);
		String id = e.getTextContent();
		return id;
	}

	/**
	 * 获取xml格式开始标签，如root  body  head
	 * @param element
	 * @return
	 */
	public static String getStartElement(String element) {
		return "<" + element + ">";
	}

	/**
	 * 获取xml格式结束标签，如root  body  head
	 * @param element
	 * @return
	 */
	public static String getEndElement(String element) {
		return "</" + element + ">";
	}

	/**
	 * 插入标签中间内容
	 * @return
	 */
	public static String addNode(String name, String value) {
		if (value == null) {
			value = "";
		}
		return "<" + name.trim() + ">" + value.trim() + "</" + name.trim() + ">";
	}

	/**
	 * 把对象转换为xml格式的字符串
	 * @param object
	 * @return
	 */
	public static String toXmlStrForObjcet(Object object) {
		String xmlStr = "";
		if (object != null) {
			StringWriter xml = new StringWriter();
			JAXB.marshal(object, xml);
			xmlStr = xml.toString();
		}
		return xmlStr;
	}

	/**
	 * 把Map对象转换为xml格式的字符串
	 * @return
	 */
	public static String toXmlStrForMap(Map<String, Object> map) {
		String xml =getXmlHeadUTF8();
		xml = xml + "<root><head></head><body>";
		if (map != null) {
			Object s[] = map.keySet().toArray();
			for (int i = 0; i < map.size(); i++) {
				xml = xml + addNode(s[i].toString(), String.valueOf(map.get(s[i])));
			}
		}
		xml = xml + "</body></root>";
		String xmlStr = xml.toString();
		return xmlStr;
	}

	/**
	 * 把Json对象转换为xml格式的字符串
	 * @return
	 */
	public static String toXmlStrForJsonObject(JSONObject jsonObject) {
		StringBuffer xml = new StringBuffer(getXmlHeadUTF8());
		xml.append("<root><head></head><body>");
		if (jsonObject != null) {
			Object s[] = jsonObject.keySet().toArray();
			for (int i = 0; i < jsonObject.size(); i++) {
				String key = String.valueOf(s[i]);
				Object value = jsonObject.get(s[i]);
				if (value instanceof JSONArray) {
					// 判断此时key的value是否是json数组，再递归拼接
					xml.append(jsonArrayToXml((JSONArray) value, key));
				}else if (value instanceof JSONObject) {
					JSONObject valueJsonObject = (JSONObject)value;
					xml.append("<"+key+">");
					for (int j = 0; j < jsonObject.size(); j++) {
						Object c[] = valueJsonObject.keySet().toArray();
						String key2 = String.valueOf(c[j]);
						Object value2 = valueJsonObject.get(c[j]);
						xml.append(addNode(key2, String.valueOf(value2)));
					}
					xml.append("</"+key+">");
				}else{
					xml.append(addNode(key, String.valueOf(value)));
				}
			}
		}
		xml.append("</body></root>");
		String xmlStr = xml.toString();
		return xmlStr;
	}

	/**
     * 把Json数组对象转换为xml格式的字符串
	 * @param jsonArray
     * @param childrenElement 数组节点的标签名称
	 * @return
     */
	public static String toXmlStrForJsonArray(JSONArray jsonArray,String childrenElement){
		StringBuffer xml = new StringBuffer(getXmlHeadUTF8());
		xml.append("<root><head></head><body>");

		xml.append(jsonArrayToXml(jsonArray,childrenElement));

		xml.append("</body></root>");
		String xmlStr = xml.toString();
		return xmlStr;
	}


	/**
	 *
	 * @param jsonArray
	 * @param childrenElement
	 * @return
	 */
	private static String jsonArrayToXml(JSONArray jsonArray,String childrenElement) {
		StringBuffer xml = new StringBuffer("");
		if (jsonArray != null && jsonArray.size()>0) {
			for (int i = 0; i < jsonArray.size(); i++) {
				xml.append("<"+childrenElement+">");
				JSONObject jsonObject = (JSONObject) jsonArray.get(i);
				Object s[] = jsonObject.keySet().toArray();
				for (int j = 0; j < jsonObject.size(); j++) {
					String key = String.valueOf(s[j]);
					Object value = jsonObject.get(s[j]);
//					System.out.println(key+"-->"+value);
					if (value instanceof JSONArray) {
						// 判断此时key的value是否是json数组，再递归拼接
						xml.append(jsonArrayToXml((JSONArray) value, key));
					}else{
						xml.append(addNode(key, String.valueOf(value)));
					}
				}
				xml.append("</"+childrenElement+">");

			}

		}
		String xmlStr = xml.toString();
		return xmlStr;
	}

	/**
	 * 把xml格式字符串转换对应对象
	 * @return

	public static Object toObject(String xmlStr, Class<?> obj) {
		Object object = null;
		try {
			JAXBContext jaxbContext = JAXBContext.newInstance(obj);
			Unmarshaller um = jaxbContext.createUnmarshaller();
			object = (Object) um.unmarshal(new ByteArrayInputStream(xmlStr.getBytes("utf-8")));
		} catch (JAXBException e) {
			e.printStackTrace();
			object = null;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return object;
	}
	 */

	public static void main(String[] args) throws SAXException, IOException {

		String str1="";

//		//1、对象转xml字符串
//		XmlTestObj testObj = new XmlTestObj();
//		testObj.setName("张三");
//		testObj.setAge(10);
//		testObj.setDate(new Date());
//		testObj.setMoney(100.12);
//		testObj.setTitle("测试");
//		System.out.println("1、对象转xml字符串");
//		System.out.println("转换前："+testObj);
//		str1=XmlStrUtil.toXmlStrForObjcet(testObj);
//		System.out.println("转换后："+str1);
//		System.out.println("\n");

		//2、map转xml字符串
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("user_name","张三");
		map.put("User_Sex","男");
		map.put("user_Age",100);
		map.put("datetime",new Date());
		System.out.println("2、Map转xml字符串");
		System.out.println("转换前："+map);
		str1=XmlStrUtil.toXmlStrForMap(map);
		System.out.println("转换后："+str1);
		System.out.println("\n");

		JSONObject jsonObject1 = new JSONObject();
		jsonObject1.put("user_name","张三");
		jsonObject1.put("User_Sex","女");
		jsonObject1.put("user_price",20.10);
		System.out.println("3、json对象转xml字符串");
		System.out.println("转换前："+jsonObject1);
		str1=XmlStrUtil.toXmlStrForJsonObject(jsonObject1);
		System.out.println("转换后："+str1);
		System.out.println("\n");

		JSONObject jsonObject2 = new JSONObject();
		jsonObject2.put("user_name","王五");
		jsonObject2.put("User_Sex","男");
		jsonObject2.put("user_price",3.12);

		JSONArray jsonArray3 = new JSONArray();
		JSONObject jsonObject31 = new JSONObject();
		jsonObject31.put("title","李四儿子");
		jsonObject31.put("address","天津市");
		JSONObject jsonObject32 = new JSONObject();
		jsonObject32.put("title","李四女儿");
		jsonObject32.put("address","北京市");
		JSONObject jsonObject321 = new JSONObject();
		JSONObject jsonObject322 = new JSONObject();
		jsonObject321.put("dist","海淀区");
		jsonObject322.put("dist","朝阳区");
		JSONArray jsonArray321 = new JSONArray();
		jsonArray321.add(jsonObject321);
		jsonArray321.add(jsonObject322);
		jsonObject32.put("distList",jsonArray321);

		jsonArray3.add(jsonObject31);
		jsonArray3.add(jsonObject32);
		JSONObject jsonObject3 = new JSONObject();
		jsonObject3.put("childrenList",jsonArray3);


		JSONArray jsonArray = new JSONArray();
		jsonArray.add(jsonObject1);
		jsonArray.add(jsonObject2);
		jsonArray.add(jsonObject3);


		System.out.println("4、jsonArray转xml字符串");
		System.out.println("转换前："+jsonArray.toString());
		str1=XmlStrUtil.toXmlStrForJsonArray(jsonArray,"item");
		System.out.println("转换后："+str1);
		System.out.println("\n");

		String str2="{\"LogType\":\"用户操作日志\",\"LogInfo\":[{\"Error_Code\":\"\",\"Num_ID\":\"153296050726810\",\"Operate_Result\":\"1\",\"Operate_Time\":\"20180807091027\",\"Operate_Type\":\"0\",\"Organization\":\"宁夏公安厅\",\"Organization_ID\":\"640000000000\",\"Terminal_ID\":\"10.196.30.244\",\"User_ID\":\"640323199510240612\",\"User_Name\":\"test1\"},{\"Error_Code\":\"3004\",\"Num_ID\":\"153296050726810\",\"Operate_Result\":\"0\",\"Operate_Time\":\"20180807103350\",\"Operate_Type\":\"0\",\"Organization\":\"宁夏公安厅\",\"Organization_ID\":\"640000000000\",\"Terminal_ID\":\"10.196.30.244\",\"User_ID\":\"640323199510240612\",\"User_Name\":\"test2\"}]}";
		System.out.println(XmlStrUtil.toXmlStrForJsonObject(JSONObject.fromObject(str2)));
//		str2="[{\"user_name\":\"张三\",\"User_Sex\":\"女\",\"user_price\":20.1},{\"user_name\":\"王五\",\"User_Sex\":\"男\",\"user_price\":3.12},{\"childrenList\":[{\"title\":\"李四儿子\",\"address\":\"天津市\"},{\"title\":\"李四女儿\",\"address\":\"北京市\",\"distList\":[{\"dist\":\"海淀区\"},{\"dist\":\"朝阳区\"}]}]}]";
//		System.out.println(XmlStrUtil.toXmlStrForJsonArray(JSONArray.fromObject(str2),"items"));

	}

}

